/*
 * Date.cpp
 *
 *  Created on: 2010-9-15
 *      Author: zhouuchu
 */
#include "StdAfx.h"
#include "Date.h"

Date::Date()
{
	m_nDay = 1;
	m_nMonth = 1;
	m_nYear = 1;
}

Date::Date( const Date& other )
{
	m_nDay = other.m_nDay;
	m_nMonth = other.m_nMonth;
	m_nYear = other.m_nYear;
}

Date::Date( const int nDay, const int nMonth, const int nYear )
{
	if (    nDay > 0
		 && nMonth > 0
		 && nYear > 0)
	{
		m_nDay = nDay;
		m_nMonth = nMonth;
		m_nYear = nYear;
	}
}

Date::~Date() {
	// TODO Auto-generated destructor stub
}

const int Date::operator-( Date& other )
{
	int nRtn = 0;
	if ( m_nYear < m_nYear)
	{
		return 0;
	}

	while (m_nYear > other.m_nYear)
	{
		m_nYear--;
		nRtn += 365;
		if (IsLeap())
			nRtn++;
	}
	nRtn += DayInYear();
	nRtn -= other.DayInYear();
	if (nRtn<0)
	{
		return 0;
	}
	// if the other year is a leap year, the day plus twice
	// they are in the first loop and DayInYear() interface
	if (IsLeap())
	{
		nRtn--;
	}

	return nRtn;
}

const Date& Date::operator-(const int nDay)
{
	int nLeft = nDay;
	while( nLeft>=0 )
	{
		if ( 0 == m_nDay )
		{
			if (m_nMonth>1)
			{
				m_nMonth--;
				m_nDay = DayList[m_nMonth-1];
				if ( 2 == m_nMonth
					&& IsLeap() )
				{
					m_nDay++;
				}
			}
			else
			{
				m_nYear--;
				m_nMonth = 12;
				m_nDay = 31;
			}
		}

		if ( 0 == nLeft)
		{
			break;
		}
		if (m_nDay < nLeft)
		{
			nLeft -= m_nDay;
			m_nDay = 0;
		}
		else
		{
			m_nDay -= nLeft;
			nLeft = 0;
		}
	}
	return *this;
}

const Date& Date::operator+(const int nDay)
{
	int nMonthLeft = 0;
	int nLeft = nDay;
	nMonthLeft = DayList[m_nMonth-1]-m_nDay;
	if ( 2 == m_nMonth && IsLeap())
	{
		nMonthLeft ++;
	}
	if (nLeft > nMonthLeft)
	{
		nLeft -= nMonthLeft;
		m_nDay = 0;
	}
	else
	{
		m_nDay += nLeft;
		nLeft = 0;
	}

	while (nLeft > 0)
	{
		if (0 == m_nDay)
		{
			m_nMonth++;
			if (m_nMonth >12)
			{
				m_nMonth = 1;
				m_nYear++;
			}
		}

		nMonthLeft = DayList[m_nMonth-1];
		if ( 2 == m_nMonth && IsLeap())
		{
			nMonthLeft ++;
		}

		if ( nLeft > nMonthLeft )
		{
			nLeft -= nMonthLeft;
		}
		else
		{
			m_nDay += nLeft;
			nLeft = 0;
		}
	}

	return *this;
}

const Date& Date::operator=( const Date& other )
{
	if (this != &other)
	{
		m_nDay = other.m_nDay;
		m_nMonth = other.m_nMonth;
		m_nYear = other.m_nYear;
	}
	return *this;
}

bool Date::IsLeap()
{
	bool bRtn = 0;

	bRtn = ( 0 == m_nYear % 4 );
	if ( bRtn )
	{
		bRtn = (int)(m_nYear % 100);
		if ( !bRtn )
		{
			bRtn = ( 0 == m_nYear % 400 );
		}
	}
	return bRtn;
}

int Date::DayInYear()
{
	int nRtn = m_nDay;
	if ( m_nMonth > 2 && IsLeap())
	{
		nRtn++;
	}

	while (m_nMonth > 1)
	{
		m_nMonth--;
		nRtn += DayList[m_nMonth-1];
	}
	return nRtn;
}

